﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Diagnostics;

namespace Models
{
    public class DataAccess : DataAccessBase
    {
        #region Creation

        public DataAccess(DataAccessConnection state = DataAccessConnection.Open)
            : base(state)
        {
        }

        #endregion

        #region Afdelinger

        // Opret en afdeling, returner objekt af afdelingen
        public Afdeling OpretAfdeling(string navn)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_OpretAfdeling";
            command.Parameters.AddWithValue("@Navn", navn);
            object afdelingsId = command.ExecuteScalar();

            if (afdelingsId != null)
            {
                return new Afdeling((int)afdelingsId, navn);
            }

            return null;
        }

        // Redigere en afdelings navn
        public bool RedigerAfdeling(Afdeling afdeling, string navn)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_RedigerAfdeling";
            command.Parameters.AddWithValue("@AfdelingsId", afdeling.AfdelingsId);
            command.Parameters.AddWithValue("Navn", navn);

            int rowCount = (Int32)command.ExecuteScalar();

            return rowCount > 0;
        }

        // Fjern en afdeling fra databasen
        public bool FjernAfdeling(Afdeling afdeling)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_FjernAfdeling";
            command.Parameters.AddWithValue("@AfdelingsId", afdeling.AfdelingsId);
            int rowCount = (Int32)command.ExecuteScalar();

            return rowCount > 0;
        }

        // Henter alle afdelinger
        public IEnumerable<Afdeling> HentAlleAfdelinger()
        {
            command.Parameters.Clear();
            command.CommandText = "SP_HentAfdelinger";

            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var afdeling = new Afdeling(
                        id: (Int32)reader["AfdelingsId"],
                        navn: (string)reader["Navn"]);

                    yield return afdeling;
                }
            }
        }

        #endregion

        #region Brugere

        // hent bruger med en given afdeling
        public IEnumerable<Bruger> HentBrugereMedAfdeling(Afdeling afdeling)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_HentBrugereMedAfdelingsId";
            command.Parameters.AddWithValue("@AfdelingsId", afdeling.AfdelingsId);

            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    yield return new Bruger(
                        afdeling: afdeling,
                        brugerId: (Int32)reader["BrugerId"],
                        initialer: (string)reader["Initialer"],
                        navn: (string)reader["Navn"]);
                }
            }
        }

        // opret en ny bruger
        public Bruger OpretBruger(Afdeling afdeling, string initialer, string navn)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_OpretBruger";
            command.Parameters.AddWithValue("@Initialer", initialer);
            command.Parameters.AddWithValue("@Navn", navn);
            command.Parameters.AddWithValue("@AfdelingsId", afdeling.AfdelingsId);

            int brugerId = (Int32)command.ExecuteScalar();

            return new Bruger(afdeling, brugerId, initialer, navn);
        }

        // Rediger bruger, definer hvilken afdeling brugeren skal have, samt initialer og navn
        public bool RedigerBruger(Bruger bruger, Afdeling afdeling, string initialer, string navn)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_RedigerBruger";
            command.Parameters.AddWithValue("@Initialer", initialer);
            command.Parameters.AddWithValue("@Navn", navn);
            command.Parameters.AddWithValue("@AfdelingsId", afdeling.AfdelingsId);
            command.Parameters.AddWithValue("@BrugerId", bruger.BrugerId);
            int rowCount = (Int32)command.ExecuteScalar();

            return rowCount > 0;
        }

        // Fjern bruger fra databasen
        public bool FjernBruger(Bruger bruger)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_FjernBruger";
            command.Parameters.AddWithValue("@BrugerId", bruger.BrugerId);
            int rowCount = (Int32)command.ExecuteScalar();

            return rowCount > 0;
        }

        #endregion

        #region Enheder

        // Henter alle enheder fra databasen
        public IEnumerable<Enhed> HentAlleEnheder()
        {
            #region yield return alle Computer objekter

            command.Parameters.Clear();
            command.CommandText = "SP_HentAlleComputerEnheder";
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var computer = new Computer(
                        enhedsId: (Int32)reader["EnhedsId"],
                        navn: (string)reader["Navn"],
                        totalAntal: (Int32)reader["TotalAntal"],
                        oprettelsesDato: (DateTime)reader["OprettelsesDato"],
                        hdd: (string)reader["HDD"],
                        cpu: (string)reader["CPU"],
                        gpu: (string)reader["GPU"],
                        bundkort: (string)reader["Bundkort"],
                        ram: (string)reader["RAM"],
                        skærm: (string)reader["Skærm"]
                        );

                    yield return computer;
                }
            }

            #endregion

            #region yield return alle Diverse objekter

            command.Parameters.Clear();
            command.CommandText = "SP_HentAlleDiverseEnheder";
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var diverse = new Diverse(
                        enhedsId: (Int32)reader["EnhedsId"],
                        navn: (string)reader["Navn"],
                        totalAntal: (Int32)reader["TotalAntal"],
                        oprettelsesDato: (DateTime)reader["OprettelsesDato"]);


                    yield return diverse;
                }
            }

            #endregion

            #region yield return alle Mobil objekter

            command.Parameters.Clear();
            command.CommandText = "SP_HentAlleMobileEnheder";
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var mobil = new Mobil(
                        enhedsId: (Int32)reader["EnhedsId"],
                        navn: (string)reader["Navn"],
                        totalAntal: (Int32)reader["TotalAntal"],
                        oprettelsesDato: (DateTime)reader["OprettelsesDato"],
                        mobilNummer: (string)reader["MobilNummer"],
                        imeiNummer: (string)reader["IMEI"]
                        );


                    yield return mobil;
                }
            }

            #endregion
        }

        #endregion

        #region Diverse Enheder

        // Henter alle diverse enheder
        public IEnumerable<Diverse> HentAlleDiverseEnheder()
        {
            command.Parameters.Clear();
            command.CommandText = "SP_HentAlleDiverseEnheder";

            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var diverse = new Diverse(
                        enhedsId: (Int32)reader["EnhedsId"],
                        navn: (string)reader["Navn"],
                        totalAntal: (Int32)reader["TotalAntal"],
                        oprettelsesDato: (DateTime)reader["OprettelsesDato"]);


                    yield return diverse;
                }
            }
        }

        // Henter alle specifikationer til diverse enhed
        public IEnumerable<Specifikation> HentSpecifikationerFraDiverseEnhed(Diverse diverseEnhed)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_HentSpecifikationerFraEnhed";
            command.Parameters.AddWithValue("@EnhedsId", diverseEnhed.EnhedsId);

            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var specifikation = new Specifikation(
                        diverse: diverseEnhed,
                        specifikationsId: (Int32)reader["SpecifikationsId"],
                        beskrivelse: (string)reader["Beskrivelse"]);

                    yield return specifikation;
                }
            }
        }

        // Opretter diverse enhed i db
        public Diverse OpretDiverseEnhed(string navn, int totalAntal, DateTime oprettelsesDato)
        {
            try
            {
                command.Parameters.Clear();
                command.CommandText = "SP_OpretDiverseEnhed";
                command.Parameters.AddWithValue("@Navn", navn);
                command.Parameters.AddWithValue("@TotalAntal", totalAntal);
                command.Parameters.AddWithValue("@OprettelsesDato", oprettelsesDato);

                int enhedsId = (Int32)command.ExecuteScalar();
                return new Diverse(enhedsId, navn, totalAntal, oprettelsesDato);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }
            return null;
        }

        // Fjerner diverse enhed i db
        public bool FjernDiverseEnhed(Diverse diverse)
        {
            try
            {
                command.Parameters.Clear();
                command.CommandText = "SP_FjernDiverseEnhed";
                command.Parameters.AddWithValue("@EnhedsId", diverse.EnhedsId);
                int rowCount = (Int32)command.ExecuteScalar();
                return rowCount > 0;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
                throw;
            }
        }

        // Redigere diverse enhed i db
        public bool OpdaterDiverseEnhed(Diverse diverse, string navn, int antal)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_RedigerDiverseEnhed";
            command.Parameters.AddWithValue("@EnhedsId", diverse.EnhedsId);
            command.Parameters.AddWithValue("@Navn", navn);
            command.Parameters.AddWithValue("@TotalAntal", antal);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Opretter specifikation til den enkelte diverse enhed
        public Specifikation OpretSpecifikation(Diverse diverseEnhed, string beskrivelse)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_OpretSpecifikation";
            command.Parameters.AddWithValue("@EnhedsId", diverseEnhed.EnhedsId);
            command.Parameters.AddWithValue("@Beskrivelse", beskrivelse);

            int specifikationsId = (Int32)command.ExecuteScalar();
            return new Specifikation(diverseEnhed, specifikationsId, beskrivelse);
        }

        // Fjerner specifikationen til den enkelte diverse enhed
        public bool FjernSpecifikation(Specifikation specifikation)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_FjernSpecifikation";
            command.Parameters.AddWithValue("@SpecifikationsId", specifikation.SpecifikationsId);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Fjerner alle specifikationer til en diverse enhed
        public bool FjernSpecifikationMedEnhed(Diverse enhed)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_FjernSpecifikationMedEnhed";
            command.Parameters.AddWithValue("@EnhedsId", enhed.EnhedsId);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        #endregion

        #region Computere

        // Opretter computer i db
        public Computer OpretComputerEnhed(string navn, int totalAntal, DateTime oprettelsesDato, string cpu, string hdd, string gpu, string ram, string bundkort, string skærm)
        {
            try
            {
                command.Parameters.Clear();
                command.CommandText = "SP_OpretComputerEnhed";
                command.Parameters.AddWithValue("@Navn", navn);
                command.Parameters.AddWithValue("@TotalAntal", totalAntal);
                command.Parameters.AddWithValue("@OprettelsesDato", oprettelsesDato);
                command.Parameters.AddWithValue("@CPU", cpu);
                command.Parameters.AddWithValue("@HDD", hdd);
                command.Parameters.AddWithValue("@GPU", gpu);
                command.Parameters.AddWithValue("@RAM", ram);
                command.Parameters.AddWithValue("@Bundkort", bundkort);
                command.Parameters.AddWithValue("@Skærm", skærm);

                int enhedsId = (Int32)command.ExecuteScalar();
                return new Computer(enhedsId, navn, totalAntal, oprettelsesDato, cpu, hdd, gpu, ram, bundkort, skærm);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }
            return null;
        }

        // Fjerner computer i db
        public bool FjernComputerEnhed(Computer computer)
        {
            try
            {
                command.Parameters.Clear();
                command.CommandText = "SP_FjernComputerEnhed";
                command.Parameters.AddWithValue("@EnhedsId", computer.EnhedsId);
                int rowCount = (Int32)command.ExecuteScalar();
                return rowCount > 0;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
                throw;
            }
        }

        // Rediger computer i db
        public bool OpdaterComputerEnhed(Computer computer, string navn, string cpu, string hdd, string gpu, string ram, string bundkort, string skærm)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_RedigerComputerEnhed";
            command.Parameters.AddWithValue("EnhedsId", computer.EnhedsId);
            command.Parameters.AddWithValue("@Navn", navn);
            command.Parameters.AddWithValue("@CPU", cpu);
            command.Parameters.AddWithValue("@HDD", hdd);
            command.Parameters.AddWithValue("@GPU", gpu);
            command.Parameters.AddWithValue("@RAM", ram);
            command.Parameters.AddWithValue("@Bundkort", bundkort);
            command.Parameters.AddWithValue("@Skærm", skærm);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        #endregion

        #region Udlån

        // opretter udlån i db
        public Udlån OpretUdlån(int brugerId, int enhedsId, int antal, DateTime dato)
        {
            try
            {
                command.Parameters.Clear();
                command.CommandText = "SP_OpretUdlån";

                command.Parameters.AddWithValue("@BrugerId", brugerId);
                command.Parameters.AddWithValue("@EnhedsId", enhedsId);
                command.Parameters.AddWithValue("@Antal", antal);
                command.Parameters.AddWithValue("@UdlånsDato", dato);
                int rowCount = (Int32)command.ExecuteScalar();

                // hvis udlånet blev oprettet i databasen så returner nyt udlånsobjekt, ellers null
                if (rowCount > 0)
                {
                    var udlån = new Udlån(brugerId, enhedsId, antal, dato);
                    return udlån;
                }
            }
            catch (SqlException e) // der skete en sql fejl?
            {
                Debug.WriteLine(e.Message); // skriv fejlbesked til debugger
            }

            return null;
        }

        // opretter historikudlån i db
        public HistorikUdlån HistorikOpretUdlån(int brugerId, int enhedsId, int antal, DateTime startDato)
        {
            try
            {
                command.Parameters.Clear();
                command.CommandText = "SP_OpretHistorikUdlån";
                command.Parameters.AddWithValue("@BrugerId", brugerId);
                command.Parameters.AddWithValue("@EnhedsId", enhedsId);
                command.Parameters.AddWithValue("@Antal", antal);
                command.Parameters.AddWithValue("@StartDato", startDato);
                command.Parameters.AddWithValue("@SlutDato", null);
                int rowCount = (Int32)command.ExecuteScalar();

                // hvis udlånet blev oprettet i databasen så returner nyt udlånsobjekt, ellers null
                if (rowCount > 0)
                {
                    Debug.WriteLine("Historik til lån oprettet");
                    var historikUdlån = new HistorikUdlån(brugerId, enhedsId, antal, startDato, null);
                    return historikUdlån;
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }

            return null;
        }

        // Redigere historikudlånet i db
        public bool RedigerHistorikUdlån(HistorikUdlån historikUdlån, DateTime slutDato)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_RedigerHistorikUdlån";
            command.Parameters.AddWithValue("@BrugerId", historikUdlån.BrugerId);
            command.Parameters.AddWithValue("@EnhedsId", historikUdlån.EnhedsId);
            command.Parameters.AddWithValue("@Antal", historikUdlån.Antal);
            command.Parameters.AddWithValue("@StartDato", historikUdlån.StartDato);
            command.Parameters.AddWithValue("@SlutDato", slutDato);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Fjerner historikudlånet fra db
        public bool FjernHistorikUdlån(HistorikUdlån historikUdlån)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_FjernHistorikUdlån";
            command.Parameters.AddWithValue("@BrugerId", historikUdlån.BrugerId);
            command.Parameters.AddWithValue("@EnhedsId", historikUdlån.EnhedsId);
            command.Parameters.AddWithValue("@Antal", historikUdlån.Antal);
            command.Parameters.AddWithValue("@StartDato", historikUdlån.StartDato);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Fjerner udlånet fra db
        public bool FjernUdlån(Udlån udlån)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_FjernUdlån";
            command.Parameters.AddWithValue("@EnhedsId", udlån.EnhedsId);
            command.Parameters.AddWithValue("@BrugerId", udlån.BrugerId);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Fjerner alle historkudlån tilhørende en given enhed fra db
        public bool FjernHistorikUdlånMedEnhed(Enhed enhed)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_FjernHistorikUdlånMedEnhed";
            command.Parameters.AddWithValue("@EnhedsId", enhed.EnhedsId);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Fjerner alle udlån tilhørende en given enhed fra db
        public bool FjernUdlånMedEnhed(Enhed enhed)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_FjernUdlånMedEnhed";
            command.Parameters.AddWithValue("@EnhedsId", enhed.EnhedsId);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Redigere udlånet i db
        public bool OpdaterUdlån(Udlån udlån, int antal, DateTime dato)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_RedigerUdlån";
            command.Parameters.AddWithValue("@BrugerId", udlån.BrugerId);
            command.Parameters.AddWithValue("@EnhedsId", udlån.EnhedsId);
            command.Parameters.AddWithValue("@Antal", antal);
            command.Parameters.AddWithValue("@Dato", dato);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Henter alle udlån fra db
        public IEnumerable<Udlån> HentAlleUdlån()
        {
            command.Parameters.Clear();
            command.CommandText = "SP_HentAlleUdlån";

            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var udlån = new Udlån(
                        brugerId: (Int32)reader["BrugerId"],
                        enhedsId: (Int32)reader["EnhedsId"],
                        antal: (Int32)reader["Antal"],
                        udlånsDato: (DateTime)reader["UdlånsDato"]);

                    yield return udlån;
                }
            }
        }

        // Henter alle historikudlån fra db
        public IEnumerable<HistorikUdlån> HentAlleHistorikUdlån()
        {
            Command.Parameters.Clear();
            Command.CommandText = "SP_HentAlleHistorikUdlån";

            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    object dato = reader["SlutDato"];
                    DateTime? slutDato;
                    if (dato != DBNull.Value)
                    {
                        DateTime cast = (DateTime)dato;
                        slutDato = new DateTime?(cast);
                    }
                    else
                    {
                        slutDato = null;
                    }

                    var historikUdlån = new HistorikUdlån(
                        brugerId: (Int32)reader["BrugerId"],
                        enhedsId: (Int32)reader["EnhedsId"],
                        antal: (Int32)reader["Antal"],
                        startDato: (DateTime)reader["StartDato"],
                        slutDato: slutDato);

                    yield return historikUdlån;
                }
            }
        }

        #endregion

        #region Mobile Enheder

        // Opretter mobil enhed i db
        public Mobil OpretMobilEnhed(string navn, int antal, DateTime oprettelsesDato, string mobilNummer, string imeiNummer)
        {
            try
            {
                command.Parameters.Clear();
                command.CommandText = "SP_OpretMobilEnhed";
                command.Parameters.AddWithValue("@Navn", navn);
                command.Parameters.AddWithValue("@TotalAntal", antal);
                command.Parameters.AddWithValue("@OprettelsesDato", oprettelsesDato);
                command.Parameters.AddWithValue("@MobilNummer", mobilNummer);
                command.Parameters.AddWithValue("@IMEI", imeiNummer);

                int enhedsId = (Int32)command.ExecuteScalar();
                return new Mobil(enhedsId, navn, antal, oprettelsesDato, imeiNummer, mobilNummer);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
            }
            return null;
        }

        // Redigere mobil enhed i db
        public bool OpdaterMobilEnhed(Mobil mobil, string navn, string mobilNummer, string imeiNummer)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_RedigerMobilEnhed";
            command.Parameters.AddWithValue("EnhedsId", mobil.EnhedsId);
            command.Parameters.AddWithValue("@Navn", navn);
            command.Parameters.AddWithValue("@MobilNummer", mobilNummer);
            command.Parameters.AddWithValue("@IMEI", imeiNummer);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Fjerner den mobile enhed fra db
        public bool FjernMobilEnhed(Mobil mobil)
        {
            try
            {
                command.Parameters.Clear();
                command.CommandText = "SP_FjernMobilEnhed";
                command.Parameters.AddWithValue("@EnhedsId", mobil.EnhedsId);
                int rowCount = (Int32)command.ExecuteScalar();
                return rowCount > 0;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
                throw;
            }
        }

        #endregion

        #region Software

        // Henter alle softwareudlån fra db
        public IEnumerable<SoftwareUdlån> HentAlleSoftwareUdlån()
        {
            command.Parameters.Clear();
            command.CommandText = "SP_HentAlleSoftwareUdlån";

            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var udlån = new SoftwareUdlån(
                        enhedsId: (Int32)reader["EnhedsId"],
                        nøgle: (Int32)reader["ProduktnøgleId"],
                        dato: (DateTime)reader["Dato"]
                    );

                    yield return udlån;
                }
            }
        }

        // Opretter software i db
        public Software OpretSoftware(string navn, DateTime dato)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_OpretSoftware";
            command.Parameters.AddWithValue("@Navn", navn);
            command.Parameters.AddWithValue("@Oprettelsesdato", dato);

            int softwareId = (Int32)command.ExecuteScalar();

            return (softwareId > 0) ? new Software(softwareId, navn, dato) : null;
        }

        // Redigere softwaren i db
        public bool OpdaterSoftware(Software software, string navn, DateTime dato)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_OpdaterSoftware";
            command.Parameters.AddWithValue("@Navn", navn);
            command.Parameters.AddWithValue("@Oprettelsesdato", dato);
            command.Parameters.AddWithValue("@SoftwareId", software.SoftwareId);

            int rowCount = (Int32)command.ExecuteScalar();
            return (rowCount > 0);
        }

        // Henter alt software fra db
        public IEnumerable<Software> HentAltSoftware()
        {
            command.Parameters.Clear();
            command.CommandText = "SP_HentAltSoftware";

            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var software = new Software(
                        (Int32)reader["SoftwareId"],
                        (String)reader["Navn"],
                        (DateTime)reader["Oprettelsesdato"]
                    );

                    yield return software;
                }
            }
        }

        // Henter alle produktnøglerne til en given software fra db
        public IEnumerable<Produktnøgle> HentProduktnøglerMedSoftware(Software software)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_HentAlleProduktnøglerMedSoftware";
            command.Parameters.AddWithValue("@SoftwareId", software.SoftwareId);
            using (var reader = command.ExecuteReader())
            {
              while (reader.Read())
                {
                    var produktnøgle = new Produktnøgle(
                        (Int32)reader["ProduktnøgleId"],
                        (Int32)reader["SoftwareId"],
                        (String)reader["Nøgle"],
                        (Int32)reader["Antal"],
                        (DateTime)reader["Udløbsdato"]
                    );

                    yield return produktnøgle;
                }
            }
        }

        // Fjerner softwareudlån med en given produktnøgle fra db
        public bool FjernSoftwareUdlånMedProduktnøgle(Produktnøgle nøgle)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_FjernSoftwareUdlånMedProduktnøgle";
            command.Parameters.AddWithValue("@ProduktnøgleId", nøgle.ProduktnøgleId);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Fjerner alle produktnøgler til en given software fra db
        public bool FjernProduktnøglerMedSoftware(Software software)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_FjernProduktnøglerMedSoftware";
            command.Parameters.AddWithValue("@SoftwareId", software.SoftwareId);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Fjerner en given software fra db
        public bool FjernSoftware(Software software)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_FjernSoftware";
            command.Parameters.AddWithValue("@SoftwareId", software.SoftwareId);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Opretter en produktnøgle til en given software i db
        public Produktnøgle OpretProduktnøgle(Software selectedSoftware, string nøgle, DateTime dato, int antal)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_OpretProduktnøgle";
            command.Parameters.AddWithValue("@SoftwareId", selectedSoftware.SoftwareId);
            command.Parameters.AddWithValue("@Nøgle", nøgle);
            command.Parameters.AddWithValue("@Udløbsdato", dato);
            command.Parameters.AddWithValue("@Antal", antal);

            int insertedId = (Int32)command.ExecuteScalar();

            return (insertedId > 0)
                       ? new Produktnøgle(insertedId, selectedSoftware.SoftwareId, nøgle, antal, dato)
                       : null;
        }

        // Redigere produktnøglen i db
        public bool OpdaterProduktnøgle(Produktnøgle produktNøgle, DateTime dato, int antal)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_RedigerProduktnøgle";
            command.Parameters.AddWithValue("@ProduktnøgleId", produktNøgle.ProduktnøgleId);
            command.Parameters.AddWithValue("@Udløbsdato", dato);
            command.Parameters.AddWithValue("@Antal", antal);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Fjerner en given produktnøgle fra db
        public bool FjernProduktnøgle(Produktnøgle produktnøgle)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_FjernProduktnøgle";
            command.Parameters.AddWithValue("@ProduktnøgleId", produktnøgle.ProduktnøgleId);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        // Opretter et softwareudlån i db
        public SoftwareUdlån OpretSoftwareUdlån(Computer computer, Produktnøgle nøgle, DateTime dato)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_OpretSoftwareUdlån";
            command.Parameters.AddWithValue("@EnhedsId", computer.EnhedsId);
            command.Parameters.AddWithValue("@ProduktnøgleId", nøgle.ProduktnøgleId);
            command.Parameters.AddWithValue("@Dato", dato);

            int rowCount = (Int32)command.ExecuteScalar();

            return (rowCount > 0)
                       ? new SoftwareUdlån(computer.EnhedsId, nøgle.ProduktnøgleId, dato)
                       : null;
        }

        // Fjerner et softwareudlån fra db
        public bool FjernSoftwareUdlån(Computer computer, Produktnøgle nøgle)
        {
            command.Parameters.Clear();
            command.CommandText = "SP_FjernSoftwareUdlån";
            command.Parameters.AddWithValue("@EnhedsId", computer.EnhedsId);
            command.Parameters.AddWithValue("@ProduktnøgleId", nøgle.ProduktnøgleId);

            int rowCount = (Int32)command.ExecuteScalar();
            return rowCount > 0;
        }

        #endregion
    }
}